/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package replic.console;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import replic.commons.Message;
import replic.commons.OutputMessage;
import replic.driver.RepliCDriver;

/**
 *
 * @author Leonardo Oliveira Moreira
 */
public class RepliCTerminalDriver extends RepliCTerminal {
    
    public RepliCTerminalDriver(int terminalId, File logFile, String databaseName, String replicHost, int replicPort) {
        super(terminalId, logFile, databaseName, replicHost, replicPort);
    }

    @Override
    public void run() {
        try {
            DriverManager.registerDriver(new RepliCDriver());            
            Connection connection = DriverManager.getConnection("jdbc:replic://" + replicHost + ":" + replicPort + "/" + databaseName);
            OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connection to RepliC Service");
            if (connection != null && !connection.isClosed()) {
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connected to RepliC Service");
                TransactionResult transactionResult = null;
                Statement statement = null;
                for (int i = 0; i < messageList.size(); i++) {
                    Message m = messageList.get(i);
                    m.setStartTime(System.currentTimeMillis());
                    if (connection != null && !connection.isClosed()) {
                        if (transactionResult == null && statement == null) {
                            transactionResult = new TransactionResult();
                            transactionResult.setStartTime(System.currentTimeMillis());
                            statement = connection.createStatement();
                        }
                        switch (m.getSqlType()) {
                            case Message.SQL_SELECT : {
                                long startTime = System.currentTimeMillis();
                                ResultSet resultSet = statement.executeQuery(m.getSql());
                                long endTime = System.currentTimeMillis();
                                int count = 0;
                                while (resultSet != null && resultSet.next()) {
                                    count++;
                                }
                                resultSet.close();
                                m.setSqlAffectedLines(count);
                                m.setSqlResponseTime(endTime - startTime);
                                break;
                            }
                            case Message.SQL_INSERT : {
                                long startTime = System.currentTimeMillis();
                                int count = statement.executeUpdate(m.getSql());
                                long endTime = System.currentTimeMillis();
                                m.setSqlAffectedLines(count);
                                m.setSqlResponseTime(endTime - startTime);
                                break;
                            }
                            case Message.SQL_UPDATE : {
                                long startTime = System.currentTimeMillis();
                                int count = statement.executeUpdate(m.getSql());
                                long endTime = System.currentTimeMillis();
                                m.setSqlAffectedLines(count);
                                m.setSqlResponseTime(endTime - startTime);
                                break;
                            }
                            case Message.SQL_DELETE : {
                                long startTime = System.currentTimeMillis();
                                int count = statement.executeUpdate(m.getSql());
                                long endTime = System.currentTimeMillis();
                                m.setSqlAffectedLines(count);
                                m.setSqlResponseTime(endTime - startTime);
                                break;
                            }
                        }
                        if (m.getSqlType() == Message.SQL_COMMIT || m.getSqlType() == Message.SQL_ROLLBACK) {
                            transactionResult.setEndTime(System.currentTimeMillis());
                            statement.close();
                            statement = null;                                
                            if (m.getSqlType() == Message.SQL_COMMIT) {
                                long startTime = System.currentTimeMillis();
                                connection.commit();
                                long endTime = System.currentTimeMillis();
                                m.setSqlResponseTime(endTime - startTime);
                                m.setSqlAffectedLines(0);
                            }
                            if (m.getSqlType() == Message.SQL_ROLLBACK) {
                                long startTime = System.currentTimeMillis();
                                connection.rollback();
                                long endTime = System.currentTimeMillis();
                                m.setSqlResponseTime(endTime - startTime);
                                m.setSqlAffectedLines(0);
                            }
                            OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Transaction Executed in " + (transactionResult.getEndTime() - transactionResult.getStartTime()) + " ms [" + (messageList.size() - (i + 1)) + " remaining operation(s)]");
                            transactionResults.add(transactionResult);
                            transactionResult = null;
                        }
                        else {
                            transactionResult.incrementOperationNumber();
                        }
                    }
                    m.setFinishTime(System.currentTimeMillis());
                }
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Closing Connection");
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + transactionResults.size() + " transaction(s) executed");
                connection.close();
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connection Closed");
            }
        } catch (SQLException ex) {
            OutputMessage.println(ex.getMessage());
            executing = false;
            return;
        }
        executing = false;
    }
        
}